Be sure to lock purely optional dependencies
authorAlex Crichton <alex@alexcrichton.com>
Wed, 5 Nov 2014 19:13:04 +0000 (11:13 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Wed, 5 Nov 2014 19:39:57 +0000 (11:39 -0800)
Previously all features were traversed when adding information to the lockfile,
but the traversal forgot to add optional dependencies that did not have a
corresponding feature.

Closes #801

src/cargo/core/resolver/mod.rs
tests/test_cargo_features.rs

index 03ae387d318e9a69e14f4cd53372058cd398ab3e..326c3244700a1aa787f904df78192c5ea430a648 100644 (file)
@@ -437,6 +437,10 @@ fn build_features(s: &Summary, method: ResolveMethod)
                 try!(add_feature(s, key.as_slice(), &mut deps, &mut used,
                                  &mut visited));
             }
+            for dep in s.get_dependencies().iter().filter(|d| d.is_optional()) {
+                try!(add_feature(s, dep.get_name(), &mut deps, &mut used,
+                                 &mut visited));
+            }
         }
         ResolveRequired(_, requested_features, _, _) =>  {
             for feat in requested_features.iter() {
index cc0e8ab5a9a09c65bd35a4edeb9bc69492b801df..fa3d1111260c834a47ba98b9fd24072f4c716898 100644 (file)
@@ -1,3 +1,5 @@
+use std::io::File;
+
 use support::{project, execs, cargo_dir};
 use support::COMPILING;
 use support::paths::PathExt;
@@ -584,3 +586,61 @@ test!(transitive_features {
     assert_that(p.cargo_process("build").arg("--features").arg("foo"),
                 execs().with_status(0));
 })
+
+test!(everything_in_the_lockfile {
+    let p = project("foo")
+        .file("Cargo.toml", r#"
+            [project]
+            name = "foo"
+            version = "0.0.1"
+            authors = []
+
+            [features]
+            f1 = ["d1/f1"]
+            f2 = ["d2"]
+
+            [dependencies.d1]
+            path = "d1"
+            [dependencies.d2]
+            path = "d2"
+            optional = true
+            [dependencies.d3]
+            path = "d3"
+            optional = true
+        "#)
+        .file("src/main.rs", "fn main() {}")
+        .file("d1/Cargo.toml", r#"
+            [package]
+            name = "d1"
+            version = "0.0.1"
+            authors = []
+
+            [features]
+            f1 = []
+        "#)
+        .file("d1/src/lib.rs", "")
+        .file("d2/Cargo.toml", r#"
+            [package]
+            name = "d2"
+            version = "0.0.2"
+            authors = []
+        "#)
+        .file("d2/src/lib.rs", "")
+        .file("d3/Cargo.toml", r#"
+            [package]
+            name = "d3"
+            version = "0.0.3"
+            authors = []
+
+            [features]
+            f3 = []
+        "#)
+        .file("d3/src/lib.rs", "");
+
+    assert_that(p.cargo_process("fetch"), execs().with_status(0));
+    let lockfile = p.root().join("Cargo.lock");
+    let lockfile = File::open(&lockfile).read_to_string().unwrap();
+    assert!(lockfile.contains(r#"name = "d1""#), "d1 not found\n{}", lockfile);
+    assert!(lockfile.contains(r#"name = "d2""#), "d2 not found\n{}", lockfile);
+    assert!(lockfile.contains(r#"name = "d3""#), "d3 not found\n{}", lockfile);
+})